1 분 소요

Closure 란?

앞서 스코프를 배우면서 마지막 예제의 경우, 이상한 결과가 도출 되는 것을 봤었다.

const a = 1;

function print() {
  console.log(a);
}

print();

전역 변수 a에 1을 할당을 하고, print 함수를 만들었고 실행을 하였다. 이때 함수 스코프 내의 a의 값은 할당 하지 않았고, 매개변수로 전달하지도 않았기 때문에 a를 출력을 했을 때 undefined가 출력이 되어야 할 것이다. 하지만, 1이 출력되는 것을 볼 수 있었다. 이는 Closure때문에 출력이 되는 것이다.

Closure란 주변 state(lexical environment를 의미)에 대한 참조와 함께 묶인 함수의 조합이다. 다시말해서, closure는 내부함수가 외부 함수의 스코프에 접근할 수 있게 해준다. 자바스크립트에서 closure는 함수 생성 시간에 함수가 생성될 때마다 만들어진다.

Lexical Environment란 자바스크립트 엔진이 현재 읽고 있는 코드의 스코프 혹은 Environment를 말한다.

여기서 앞서 이야기 했던 Scope Chain의 개념이 필요하다. 스코프 마다 Lexical Environment가 존재하는데, 자신의 Lexical Scope 밖으로 연결 할 수 있는 연결 고리를 Scope Chain이라고 한다. 즉, 부모의 Environment의 변수들에 접근할 수 있는 역할을 해준다.

Lexical scoping

Lexical scoping은 중첩함수에서 변수 이름이 확인되는 방식을 정의한다.

function outer() {
  const name = "abc";
  function inner() {
    console.log(name);
  }
  inner();
}

outer();

위의 예제에서의 inner 함수는 outer 함수의 내부에서 선언이 되었다. 따라서 inner 함수의 상위 스코프는 outer 함수이다. 동작 원리를 살펴보자.

  1. 자바스크립트가 코드를 읽는다.
  2. outer 함수의 Lexical Environment가 생성되고, 변수가 저장이 된다.
  3. inner 함수의 Lexical Environment가 생성된다.
  4. outer 함수를 호출한다.
  5. inner 함수가 실행이 된다.
  6. inner 함수 스코프 내에서 name을 찾는다. 검색이 안되면, 부모 스코프 즉, outer 스코프 내에서 name을 찾는다.
  7. name을 찾았고, 출력을 한다.

이렇게 함수 스코프가 중첩이 된 경우, 내부 함수 스코프의 Lexical Environment는 외부 함수 스코프의 Lexical Environment를 참조 할 수 있는 환경 즉, Scope Chain에 의해 Closure가 발생이 되는 것이다.

function scope vs block scope 차이 알아보기

Closure를 쓰면 좋은점

  1. 상태 유지가 된다.

  2. 데이터의 은닉화

댓글남기기